{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Constrained K-Means demo - Chicago Weather Dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## H2O K-Means algorithm\n",
    "\n",
    "K-Means falls in the general category of clustering algorithms. Clustering is a form of unsupervised learning that tries to find structures in the data without using any labels or target values. Clustering partitions a set of observations into separate groupings such that observation in a given group is more similar to another observation in the same group than to another observation in a different group.\n",
    "\n",
    "![kmeans](https://media0.giphy.com/media/12vVAGkaqHUqCQ/giphy.gif?cid=790b7611178aaedddb5b58de2ef94d55dc6c3feecd2d02f2&rid=giphy.gif)\n",
    "\n",
    "More about H2O K-means Clustering: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/k-means.html\n",
    "\n",
    "## Constrained K-Means algorithm in H2O\n",
    "\n",
    "Using the `cluster_size_constraints` parameter, a user can set the minimum size of each cluster during the training by an array of numbers. The size of the array must be equal as the `k` parameter.\n",
    "\n",
    "To satisfy the custom minimal cluster size, the calculation of clusters is converted to the Minimal Cost Flow problem. Instead of using the Lloyd iteration algorithm, a graph is constructed based on the distances and constraints. The goal is to go iteratively through the input edges and create an optimal spanning tree that satisfies the constraints.\n",
    "\n",
    "![mcf](https://adared.ch/wp-content/uploads/2015/11/mcf.png)\n",
    "\n",
    "More information about how to convert the standard K-means algorithm to the Minimal Cost Flow problem is described in this paper: https://pdfs.semanticscholar.org/ecad/eb93378d7911c2f7b9bd83a8af55d7fa9e06.pdf.\n",
    "\n",
    "**Minimum-cost flow problem can be efficiently solved in polynomial time. Currently, the performance of this implementation of Constrained K-means algorithm is slow due to many repeatable calculations which cannot be parallelized and more optimized at H2O backend.**\n",
    "\n",
    "Expected time with various sized data:\n",
    "* 5 000 rows, 5 features   ~ 0h  4m  3s\n",
    "* 10 000 rows, 5 features  ~ 0h  9m 21s\n",
    "* 15 000 rows, 5 features  ~ 0h 22m 25s\n",
    "* 20 000 rows, 5 features  ~ 0h 39m 27s\n",
    "* 25 000 rows, 5 features  ~ 1h 06m  8s\n",
    "* 30 000 rows, 5 features  ~ 1h 26m 43s\n",
    "* 35 000 rows, 5 features  ~ 1h 44m  7s\n",
    "* 40 000 rows, 5 features  ~ 2h 13m 31s\n",
    "* 45 000 rows, 5 features  ~ 2h  4m 29s\n",
    "* 50 000 rows, 5 features  ~ 4h  4m 18s\n",
    "\n",
    "(OS debian 10.0 (x86-64), processor Intel© Core™ i7-7700HQ CPU @ 2.80GHz × 4, RAM 23.1 GiB)\n",
    "\n",
    "## Shorter time using Aggregator Model\n",
    "\n",
    "To solve Constrained K-means in a shorter time, you can used the H2O Aggregator model to aggregate data to smaller size first and then pass these data to the Constrained K-means model to calculate the final centroids to be used with scoring. The results won't be as accurate as a result from a model with the whole dataset. However, it should help solve the problem of a huge datasets.\n",
    "\n",
    "However, there are some assumptions:\n",
    "* the large dataset has to consist of many similar data points - if not, the insensitive aggregation can break the structure of the dataset\n",
    "* the resulting clustering may not meet the initial constraints exactly when scoring (this also applies to Constrained K-means model, scoring use only result centroids to score and no constraints defined before)\n",
    "\n",
    "The H2O Aggregator method is a clustering-based method for reducing a numerical/categorical dataset into a dataset with fewer rows. Aggregator maintains outliers as outliers but lumps together dense clusters into exemplars with an attached count column showing the member points.\n",
    "\n",
    "More about H2O Aggregator: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/aggregator.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "versionFromGradle='3.29.0',projectVersion='3.29.0.99999',branch='maurever_PUBDEV-6447_constrained_kmeans_improvement',lastCommitHash='162ceb18eae8b773028f27b284129c3ef752d001',gitDescribe='jenkins-master-4952-11-g162ceb18ea-dirty',compiledOn='2020-02-20 15:01:59',compiledBy='mori'\n",
      "Checking whether there is an H2O instance running at http://192.168.59.147:54321 . connected.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div style=\"overflow:auto\"><table style=\"width:50%\"><tr><td>H2O cluster uptime:</td>\n",
       "<td>12 mins 05 secs</td></tr>\n",
       "<tr><td>H2O cluster timezone:</td>\n",
       "<td>Europe/Berlin</td></tr>\n",
       "<tr><td>H2O data parsing timezone:</td>\n",
       "<td>UTC</td></tr>\n",
       "<tr><td>H2O cluster version:</td>\n",
       "<td>3.29.0.99999</td></tr>\n",
       "<tr><td>H2O cluster version age:</td>\n",
       "<td>1 hour and 28 minutes </td></tr>\n",
       "<tr><td>H2O cluster name:</td>\n",
       "<td>mori</td></tr>\n",
       "<tr><td>H2O cluster total nodes:</td>\n",
       "<td>1</td></tr>\n",
       "<tr><td>H2O cluster free memory:</td>\n",
       "<td>5.102 Gb</td></tr>\n",
       "<tr><td>H2O cluster total cores:</td>\n",
       "<td>8</td></tr>\n",
       "<tr><td>H2O cluster allowed cores:</td>\n",
       "<td>8</td></tr>\n",
       "<tr><td>H2O cluster status:</td>\n",
       "<td>locked, healthy</td></tr>\n",
       "<tr><td>H2O connection url:</td>\n",
       "<td>http://192.168.59.147:54321</td></tr>\n",
       "<tr><td>H2O connection proxy:</td>\n",
       "<td>None</td></tr>\n",
       "<tr><td>H2O internal security:</td>\n",
       "<td>False</td></tr>\n",
       "<tr><td>H2O API Extensions:</td>\n",
       "<td>Amazon S3, XGBoost, Algos, AutoML, Core V3, TargetEncoder, Core V4</td></tr>\n",
       "<tr><td>Python version:</td>\n",
       "<td>3.7.3 candidate</td></tr></table></div>"
      ],
      "text/plain": [
       "--------------------------  ------------------------------------------------------------------\n",
       "H2O cluster uptime:         12 mins 05 secs\n",
       "H2O cluster timezone:       Europe/Berlin\n",
       "H2O data parsing timezone:  UTC\n",
       "H2O cluster version:        3.29.0.99999\n",
       "H2O cluster version age:    1 hour and 28 minutes\n",
       "H2O cluster name:           mori\n",
       "H2O cluster total nodes:    1\n",
       "H2O cluster free memory:    5.102 Gb\n",
       "H2O cluster total cores:    8\n",
       "H2O cluster allowed cores:  8\n",
       "H2O cluster status:         locked, healthy\n",
       "H2O connection url:         http://192.168.59.147:54321\n",
       "H2O connection proxy:\n",
       "H2O internal security:      False\n",
       "H2O API Extensions:         Amazon S3, XGBoost, Algos, AutoML, Core V3, TargetEncoder, Core V4\n",
       "Python version:             3.7.3 candidate\n",
       "--------------------------  ------------------------------------------------------------------"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# run h2o Kmeans\n",
    "\n",
    "# Import h2o library\n",
    "import h2o\n",
    "from h2o.estimators import H2OKMeansEstimator\n",
    "\n",
    "# init h2o cluster\n",
    "h2o.init(strict_version_check=False, url=\"http://192.168.59.147:54321\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data - Chicago Weather dataset\n",
    "\n",
    "- 5162 rows\n",
    "- 5 features (monht, day, year, maximal temperature, mean teperature)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5162, 5)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>month</th>\n",
       "      <th>day</th>\n",
       "      <th>year</th>\n",
       "      <th>maxTemp</th>\n",
       "      <th>meanTemp</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2001</td>\n",
       "      <td>23.0</td>\n",
       "      <td>14.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>2001</td>\n",
       "      <td>18.0</td>\n",
       "      <td>12.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>2001</td>\n",
       "      <td>28.0</td>\n",
       "      <td>18.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>2001</td>\n",
       "      <td>30.0</td>\n",
       "      <td>24.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>2001</td>\n",
       "      <td>36.0</td>\n",
       "      <td>30.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   month  day  year  maxTemp  meanTemp\n",
       "0      1    1  2001     23.0      14.0\n",
       "1      1    2  2001     18.0      12.0\n",
       "2      1    3  2001     28.0      18.0\n",
       "3      1    4  2001     30.0      24.0\n",
       "4      1    5  2001     36.0      30.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# load data\n",
    "import pandas as pd\n",
    "\n",
    "data = pd.read_csv(\"../../smalldata/chicago/chicagoAllWeather.csv\")\n",
    "data = data.iloc[:,[1, 2, 3, 4, 5]]\n",
    "print(data.shape)\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 0:00:00.000010\n"
     ]
    }
   ],
   "source": [
    "# import time to measure elapsed time\n",
    "from timeit import default_timer as timer\n",
    "from datetime import timedelta\n",
    "import time\n",
    "\n",
    "start = timer()\n",
    "end = timer()\n",
    "print(\"Time:\", timedelta(seconds=end-start))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Traditional K-means"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constrained K-means"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parse progress: |█████████████████████████████████████████████████████████| 100%\n",
      "kmeans Model Build progress: |████████████████████████████████████████████| 100%\n",
      "Parse progress: |█████████████████████████████████████████████████████████| 100%\n",
      "Model Details\n",
      "=============\n",
      "H2OKMeansEstimator :  K-means\n",
      "Model Key:  KMeans_model_python_1582207404277_9\n",
      "\n",
      "\n",
      "Model Summary: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>number_of_rows</th>\n",
       "      <th>number_of_clusters</th>\n",
       "      <th>number_of_categorical_columns</th>\n",
       "      <th>number_of_iterations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "      <th>total_sum_of_squares</th>\n",
       "      <th>between_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>5162.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>13948.755191</td>\n",
       "      <td>25779.0</td>\n",
       "      <td>11830.244809</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     number_of_rows  number_of_clusters  number_of_categorical_columns  \\\n",
       "0            5162.0                 3.0                            0.0   \n",
       "\n",
       "   number_of_iterations  within_cluster_sum_of_squares  total_sum_of_squares  \\\n",
       "0                  10.0                   13948.755191               25779.0   \n",
       "\n",
       "   between_cluster_sum_of_squares  \n",
       "0                    11830.244809  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "ModelMetricsClustering: kmeans\n",
      "** Reported on train data. **\n",
      "\n",
      "MSE: NaN\n",
      "RMSE: NaN\n",
      "Total Within Cluster Sum of Square Error: 13948.755224513394\n",
      "Total Sum of Square Error to Grand Mean: 25778.999972296842\n",
      "Between Cluster Sum of Square Error: 11830.244747783448\n",
      "\n",
      "Centroid Statistics: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>centroid</th>\n",
       "      <th>size</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>1.0</td>\n",
       "      <td>2503.0</td>\n",
       "      <td>6566.945375</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2.0</td>\n",
       "      <td>1527.0</td>\n",
       "      <td>4341.602251</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>3.0</td>\n",
       "      <td>1132.0</td>\n",
       "      <td>3040.207599</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     centroid    size  within_cluster_sum_of_squares\n",
       "0         1.0  2503.0                    6566.945375\n",
       "1         2.0  1527.0                    4341.602251\n",
       "2         3.0  1132.0                    3040.207599"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Scoring History: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>timestamp</th>\n",
       "      <th>duration</th>\n",
       "      <th>iterations</th>\n",
       "      <th>number_of_reassigned_observations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.002 sec</td>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.034 sec</td>\n",
       "      <td>1.0</td>\n",
       "      <td>5162.0</td>\n",
       "      <td>24519.632818</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.047 sec</td>\n",
       "      <td>2.0</td>\n",
       "      <td>637.0</td>\n",
       "      <td>14993.412521</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.058 sec</td>\n",
       "      <td>3.0</td>\n",
       "      <td>257.0</td>\n",
       "      <td>14091.382859</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.065 sec</td>\n",
       "      <td>4.0</td>\n",
       "      <td>101.0</td>\n",
       "      <td>13966.675115</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.074 sec</td>\n",
       "      <td>5.0</td>\n",
       "      <td>38.0</td>\n",
       "      <td>13951.869333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.081 sec</td>\n",
       "      <td>6.0</td>\n",
       "      <td>11.0</td>\n",
       "      <td>13949.273464</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.088 sec</td>\n",
       "      <td>7.0</td>\n",
       "      <td>6.0</td>\n",
       "      <td>13948.879016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.093 sec</td>\n",
       "      <td>8.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>13948.764310</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.098 sec</td>\n",
       "      <td>9.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>13948.759892</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.102 sec</td>\n",
       "      <td>10.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>13948.755191</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                timestamp    duration  iterations  \\\n",
       "0     2020-02-20 15:15:30   0.002 sec         0.0   \n",
       "1     2020-02-20 15:15:30   0.034 sec         1.0   \n",
       "2     2020-02-20 15:15:30   0.047 sec         2.0   \n",
       "3     2020-02-20 15:15:30   0.058 sec         3.0   \n",
       "4     2020-02-20 15:15:30   0.065 sec         4.0   \n",
       "5     2020-02-20 15:15:30   0.074 sec         5.0   \n",
       "6     2020-02-20 15:15:30   0.081 sec         6.0   \n",
       "7     2020-02-20 15:15:30   0.088 sec         7.0   \n",
       "8     2020-02-20 15:15:30   0.093 sec         8.0   \n",
       "9     2020-02-20 15:15:30   0.098 sec         9.0   \n",
       "10    2020-02-20 15:15:30   0.102 sec        10.0   \n",
       "\n",
       "    number_of_reassigned_observations  within_cluster_sum_of_squares  \n",
       "0                                 NaN                            NaN  \n",
       "1                              5162.0                   24519.632818  \n",
       "2                               637.0                   14993.412521  \n",
       "3                               257.0                   14091.382859  \n",
       "4                               101.0                   13966.675115  \n",
       "5                                38.0                   13951.869333  \n",
       "6                                11.0                   13949.273464  \n",
       "7                                 6.0                   13948.879016  \n",
       "8                                 1.0                   13948.764310  \n",
       "9                                 1.0                   13948.759892  \n",
       "10                                0.0                   13948.755191  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 0:00:00.234061\n"
     ]
    }
   ],
   "source": [
    "data_h2o = h2o.H2OFrame(data)\n",
    "\n",
    "# run h2o Kmeans to get good starting points\n",
    "h2o_km = H2OKMeansEstimator(k=3, init=\"furthest\", standardize=True)\n",
    "start = timer()\n",
    "h2o_km.train(training_frame=data_h2o)\n",
    "end = timer()\n",
    "\n",
    "user_points = h2o.H2OFrame(h2o_km.centers())\n",
    "\n",
    "# show details\n",
    "h2o_km.show()\n",
    "time_km = timedelta(seconds=end-start)\n",
    "print(\"Time:\", time_km)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "kmeans Model Build progress: |████████████████████████████████████████████| 100%\n",
      "Model Details\n",
      "=============\n",
      "H2OKMeansEstimator :  K-means\n",
      "Model Key:  KMeans_model_python_1582207404277_10\n",
      "\n",
      "\n",
      "Model Summary: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>number_of_rows</th>\n",
       "      <th>number_of_clusters</th>\n",
       "      <th>number_of_categorical_columns</th>\n",
       "      <th>number_of_iterations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "      <th>total_sum_of_squares</th>\n",
       "      <th>between_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>5162.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>14652.275631</td>\n",
       "      <td>25779.0</td>\n",
       "      <td>11126.724369</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     number_of_rows  number_of_clusters  number_of_categorical_columns  \\\n",
       "0            5162.0                 3.0                            0.0   \n",
       "\n",
       "   number_of_iterations  within_cluster_sum_of_squares  total_sum_of_squares  \\\n",
       "0                   4.0                   14652.275631               25779.0   \n",
       "\n",
       "   between_cluster_sum_of_squares  \n",
       "0                    11126.724369  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "ModelMetricsClustering: kmeans\n",
      "** Reported on train data. **\n",
      "\n",
      "MSE: NaN\n",
      "RMSE: NaN\n",
      "Total Within Cluster Sum of Square Error: 14652.275630919356\n",
      "Total Sum of Square Error to Grand Mean: 25778.999999999396\n",
      "Between Cluster Sum of Square Error: 11126.72436908004\n",
      "\n",
      "Centroid Statistics: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>centroid</th>\n",
       "      <th>size</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>1.0</td>\n",
       "      <td>2021.0</td>\n",
       "      <td>4923.251099</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2.0</td>\n",
       "      <td>2000.0</td>\n",
       "      <td>6661.188217</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>3.0</td>\n",
       "      <td>1141.0</td>\n",
       "      <td>3067.836315</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     centroid    size  within_cluster_sum_of_squares\n",
       "0         1.0  2021.0                    4923.251099\n",
       "1         2.0  2000.0                    6661.188217\n",
       "2         3.0  1141.0                    3067.836315"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Scoring History: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>timestamp</th>\n",
       "      <th>duration</th>\n",
       "      <th>iterations</th>\n",
       "      <th>number_of_reassigned_observations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:30</td>\n",
       "      <td>0.001 sec</td>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:15:54</td>\n",
       "      <td>24.140 sec</td>\n",
       "      <td>1.0</td>\n",
       "      <td>5162.0</td>\n",
       "      <td>15180.211372</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:16:16</td>\n",
       "      <td>45.825 sec</td>\n",
       "      <td>2.0</td>\n",
       "      <td>50.0</td>\n",
       "      <td>14654.534258</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:16:38</td>\n",
       "      <td>1 min  7.299 sec</td>\n",
       "      <td>3.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>14652.367654</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:16:59</td>\n",
       "      <td>1 min 28.649 sec</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14652.275631</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               timestamp           duration  iterations  \\\n",
       "0    2020-02-20 15:15:30          0.001 sec         0.0   \n",
       "1    2020-02-20 15:15:54         24.140 sec         1.0   \n",
       "2    2020-02-20 15:16:16         45.825 sec         2.0   \n",
       "3    2020-02-20 15:16:38   1 min  7.299 sec         3.0   \n",
       "4    2020-02-20 15:16:59   1 min 28.649 sec         4.0   \n",
       "\n",
       "   number_of_reassigned_observations  within_cluster_sum_of_squares  \n",
       "0                                NaN                            NaN  \n",
       "1                             5162.0                   15180.211372  \n",
       "2                               50.0                   14654.534258  \n",
       "3                                8.0                   14652.367654  \n",
       "4                                0.0                   14652.275631  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 0:01:29.918478\n"
     ]
    }
   ],
   "source": [
    "# run h2o constrained Kmeans\n",
    "h2o_km_co = H2OKMeansEstimator(k=3, user_points=user_points, cluster_size_constraints=[1000, 2000, 1000], standardize=True)\n",
    "start = timer()\n",
    "h2o_km_co.train(training_frame=data_h2o)\n",
    "end = timer()\n",
    "\n",
    "# show details\n",
    "h2o_km_co.show()\n",
    "time_km_co = timedelta(seconds=end-start)\n",
    "print(\"Time:\", time_km_co)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constrained K-means reduced data using Aggregator - changed size 1/2 of original data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aggregator Model Build progress: |████████████████████████████████████████| 100%\n",
      "kmeans Model Build progress: |████████████████████████████████████████████| 100%\n",
      "Model Details\n",
      "=============\n",
      "H2OKMeansEstimator :  K-means\n",
      "Model Key:  KMeans_model_python_1582207404277_12\n",
      "\n",
      "\n",
      "Model Summary: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>number_of_rows</th>\n",
       "      <th>number_of_clusters</th>\n",
       "      <th>number_of_categorical_columns</th>\n",
       "      <th>number_of_iterations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "      <th>total_sum_of_squares</th>\n",
       "      <th>between_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>2564.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>7292.073037</td>\n",
       "      <td>12799.0</td>\n",
       "      <td>5506.926963</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     number_of_rows  number_of_clusters  number_of_categorical_columns  \\\n",
       "0            2564.0                 3.0                            0.0   \n",
       "\n",
       "   number_of_iterations  within_cluster_sum_of_squares  total_sum_of_squares  \\\n",
       "0                   4.0                    7292.073037               12799.0   \n",
       "\n",
       "   between_cluster_sum_of_squares  \n",
       "0                     5506.926963  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "ModelMetricsClustering: kmeans\n",
      "** Reported on train data. **\n",
      "\n",
      "MSE: NaN\n",
      "RMSE: NaN\n",
      "Total Within Cluster Sum of Square Error: 7292.073036736721\n",
      "Total Sum of Square Error to Grand Mean: 12798.99999999936\n",
      "Between Cluster Sum of Square Error: 5506.926963262638\n",
      "\n",
      "Centroid Statistics: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>centroid</th>\n",
       "      <th>size</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>1.0</td>\n",
       "      <td>1004.0</td>\n",
       "      <td>2541.127853</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2.0</td>\n",
       "      <td>1000.0</td>\n",
       "      <td>3225.245253</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>3.0</td>\n",
       "      <td>560.0</td>\n",
       "      <td>1525.699931</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     centroid    size  within_cluster_sum_of_squares\n",
       "0         1.0  1004.0                    2541.127853\n",
       "1         2.0  1000.0                    3225.245253\n",
       "2         3.0   560.0                    1525.699931"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Scoring History: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>timestamp</th>\n",
       "      <th>duration</th>\n",
       "      <th>iterations</th>\n",
       "      <th>number_of_reassigned_observations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:01</td>\n",
       "      <td>0.003 sec</td>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:09</td>\n",
       "      <td>8.222 sec</td>\n",
       "      <td>1.0</td>\n",
       "      <td>2564.0</td>\n",
       "      <td>7453.636111</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:16</td>\n",
       "      <td>15.442 sec</td>\n",
       "      <td>2.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>7292.141367</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:24</td>\n",
       "      <td>22.998 sec</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>7292.076435</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:32</td>\n",
       "      <td>30.972 sec</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>7292.073037</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               timestamp    duration  iterations  \\\n",
       "0    2020-02-20 15:17:01   0.003 sec         0.0   \n",
       "1    2020-02-20 15:17:09   8.222 sec         1.0   \n",
       "2    2020-02-20 15:17:16  15.442 sec         2.0   \n",
       "3    2020-02-20 15:17:24  22.998 sec         3.0   \n",
       "4    2020-02-20 15:17:32  30.972 sec         4.0   \n",
       "\n",
       "   number_of_reassigned_observations  within_cluster_sum_of_squares  \n",
       "0                                NaN                            NaN  \n",
       "1                             2564.0                    7453.636111  \n",
       "2                                7.0                    7292.141367  \n",
       "3                                2.0                    7292.076435  \n",
       "4                                0.0                    7292.073037  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 0:00:32.137910\n"
     ]
    }
   ],
   "source": [
    "from h2o.estimators.aggregator import H2OAggregatorEstimator\n",
    "\n",
    "# original data size 5162, constraints 1000, 2000, 1000\n",
    "# aggregated data size ~ 2581, constaints 500, 1000, 500\n",
    "\n",
    "params = {\n",
    "    \"target_num_exemplars\": 2581,\n",
    "    \"rel_tol_num_exemplars\": 0.01,\n",
    "    \"categorical_encoding\": \"eigen\"\n",
    "}\n",
    "agg = H2OAggregatorEstimator(**params)\n",
    "\n",
    "start = timer()\n",
    "agg.train(training_frame=data_h2o)\n",
    "data_agg = agg.aggregated_frame\n",
    "\n",
    "# run h2o Kmeans\n",
    "h2o_km_co_agg = H2OKMeansEstimator(k=3, user_points=user_points, cluster_size_constraints=[500, 1000, 500], standardize=True)\n",
    "\n",
    "h2o_km_co_agg.train(x=[\"month\", \"day\", \"year\", \"maxTemp\", \"meanTemp\"],training_frame=data_agg)\n",
    "end = timer()\n",
    "\n",
    "# show details\n",
    "h2o_km_co_agg.show()\n",
    "time_km_co_12 = timedelta(seconds=end-start)\n",
    "print(\"Time:\", time_km_co_12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constrained K-means reduced data using Aggregator - changed size 1/4 of original data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aggregator Model Build progress: |████████████████████████████████████████| 100%\n",
      "kmeans Model Build progress: |████████████████████████████████████████████| 100%\n",
      "Model Details\n",
      "=============\n",
      "H2OKMeansEstimator :  K-means\n",
      "Model Key:  KMeans_model_python_1582207404277_14\n",
      "\n",
      "\n",
      "Model Summary: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>number_of_rows</th>\n",
       "      <th>number_of_clusters</th>\n",
       "      <th>number_of_categorical_columns</th>\n",
       "      <th>number_of_iterations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "      <th>total_sum_of_squares</th>\n",
       "      <th>between_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>1298.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>3663.728438</td>\n",
       "      <td>6477.0</td>\n",
       "      <td>2813.271562</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     number_of_rows  number_of_clusters  number_of_categorical_columns  \\\n",
       "0            1298.0                 3.0                            0.0   \n",
       "\n",
       "   number_of_iterations  within_cluster_sum_of_squares  total_sum_of_squares  \\\n",
       "0                   3.0                    3663.728438                6477.0   \n",
       "\n",
       "   between_cluster_sum_of_squares  \n",
       "0                     2813.271562  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "ModelMetricsClustering: kmeans\n",
      "** Reported on train data. **\n",
      "\n",
      "MSE: NaN\n",
      "RMSE: NaN\n",
      "Total Within Cluster Sum of Square Error: 3663.7284382884254\n",
      "Total Sum of Square Error to Grand Mean: 6476.999999999918\n",
      "Between Cluster Sum of Square Error: 2813.2715617114927\n",
      "\n",
      "Centroid Statistics: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>centroid</th>\n",
       "      <th>size</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>1.0</td>\n",
       "      <td>524.0</td>\n",
       "      <td>1358.489507</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2.0</td>\n",
       "      <td>480.0</td>\n",
       "      <td>1512.732712</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>3.0</td>\n",
       "      <td>294.0</td>\n",
       "      <td>792.506219</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     centroid   size  within_cluster_sum_of_squares\n",
       "0         1.0  524.0                    1358.489507\n",
       "1         2.0  480.0                    1512.732712\n",
       "2         3.0  294.0                     792.506219"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Scoring History: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>timestamp</th>\n",
       "      <th>duration</th>\n",
       "      <th>iterations</th>\n",
       "      <th>number_of_reassigned_observations</th>\n",
       "      <th>within_cluster_sum_of_squares</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:33</td>\n",
       "      <td>0.001 sec</td>\n",
       "      <td>0.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:35</td>\n",
       "      <td>2.760 sec</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1298.0</td>\n",
       "      <td>3686.655930</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:38</td>\n",
       "      <td>5.298 sec</td>\n",
       "      <td>2.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>3663.741297</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td></td>\n",
       "      <td>2020-02-20 15:17:42</td>\n",
       "      <td>8.967 sec</td>\n",
       "      <td>3.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3663.728438</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               timestamp    duration  iterations  \\\n",
       "0    2020-02-20 15:17:33   0.001 sec         0.0   \n",
       "1    2020-02-20 15:17:35   2.760 sec         1.0   \n",
       "2    2020-02-20 15:17:38   5.298 sec         2.0   \n",
       "3    2020-02-20 15:17:42   8.967 sec         3.0   \n",
       "\n",
       "   number_of_reassigned_observations  within_cluster_sum_of_squares  \n",
       "0                                NaN                            NaN  \n",
       "1                             1298.0                    3686.655930  \n",
       "2                                2.0                    3663.741297  \n",
       "3                                0.0                    3663.728438  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 0:00:10.153074\n"
     ]
    }
   ],
   "source": [
    "from h2o.estimators.aggregator import H2OAggregatorEstimator\n",
    "\n",
    "# original data size 5162, constraints 1000, 2000, 1000\n",
    "# aggregated data size ~ 1290, constaints 250, 500, 250\n",
    "\n",
    "params = {\n",
    "    \"target_num_exemplars\": 1290,\n",
    "    \"rel_tol_num_exemplars\": 0.01,\n",
    "    \"categorical_encoding\": \"eigen\"\n",
    "}\n",
    "agg_14 = H2OAggregatorEstimator(**params)\n",
    "\n",
    "start = timer()\n",
    "agg_14.train(training_frame=data_h2o)\n",
    "data_agg_14 = agg_14.aggregated_frame\n",
    "\n",
    "# run h2o Kmeans\n",
    "h2o_km_co_agg_14 = H2OKMeansEstimator(k=3, user_points=user_points, cluster_size_constraints=[240, 480, 240], standardize=True)\n",
    "\n",
    "h2o_km_co_agg_14.train(x=list(range(5)),training_frame=data_agg_14)\n",
    "end = timer()\n",
    "\n",
    "# show details\n",
    "h2o_km_co_agg_14.show()\n",
    "time_km_co_14 = timedelta(seconds=end-start)\n",
    "print(\"Time:\", time_km_co_14)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "variables": {
     "data.shape[0]": "5162",
     "data_agg.shape[0]": "2564",
     "data_agg_14.shape[0]": "1298",
     "print(time_km_co)": "",
     "print(time_km_co_12)": "",
     "print(time_km_co_14)": ""
    }
   },
   "source": [
    "## Time \n",
    "\n",
    "| Data | Number of rows | Time  |\n",
    "|---|---|---|\n",
    "| Original data | {{data.shape[0]}} | {{print(time_km_co)}} |\n",
    "| Aggregated data 1/2 size of original data | {{data_agg.shape[0]}} | {{print(time_km_co_12)}} |\n",
    "| Aggregated data 1/4 size of original data | {{data_agg_14.shape[0]}}| {{print(time_km_co_14)}}|\n",
    "\n",
    "## Accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "centers_km_co = h2o_km_co.centers()\n",
    "centers_km_co_agg_12 = h2o_km_co_agg.centers()\n",
    "centers_km_co_agg_14 = h2o_km_co_agg_14.centers()\n",
    "centers_all = pd.concat([pd.DataFrame(centers_km_co).sort_values(by=[0]), pd.DataFrame(centers_km_co_agg_12).sort_values(by=[0]), pd.DataFrame(centers_km_co_agg_14).sort_values(by=[0])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Difference between coordinates of original data and aggregated data "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 32.3%, transparent 32.3%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 61.7%, transparent 61.7%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#d65f5f 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 26.6%, transparent 26.6%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 29.6%, transparent 29.6%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg, transparent 73.2%, #d65f5f 73.2%, #d65f5f 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }</style><table id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >0</th>        <th class=\"col_heading level0 col1\" >1</th>        <th class=\"col_heading level0 col2\" >2</th>        <th class=\"col_heading level0 col3\" >3</th>        <th class=\"col_heading level0 col4\" >4</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0level0_row0\" class=\"row_heading level0 row0\" >1/2</th>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col0\" class=\"data row0 col0\" >0.13</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col1\" class=\"data row0 col1\" >0.209</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col2\" class=\"data row0 col2\" >-0.0635</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col3\" class=\"data row0 col3\" >1.08995</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row0_col4\" class=\"data row0 col4\" >1.13402</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0level0_row1\" class=\"row_heading level0 row1\" >1/4</th>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col0\" class=\"data row1 col0\" >0.36225</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col1\" class=\"data row1 col1\" >0.304667</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col2\" class=\"data row1 col2\" >-0.0118333</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col3\" class=\"data row1 col3\" >3.69444</td>\n",
       "                        <td id=\"T_c28e23e2_53eb_11ea_bcec_d46d6d270ab0row1_col4\" class=\"data row1 col4\" >3.45049</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fb9a062b198>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diff_first_cluster = pd.concat([centers_all.iloc[0,:] - centers_all.iloc[3,:], centers_all.iloc[0,:] - centers_all.iloc[6,:]], axis=1, ignore_index=True).transpose()\n",
    "diff_first_cluster.index = [\"1/2\", \"1/4\"]\n",
    "diff_first_cluster.style.bar(subset=[0,1,2,3,4], align='mid', color=['#d65f5f', '#5fba7d'], width=90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 38.1%, transparent 38.1%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 74.9%, transparent 74.9%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 61.9%, transparent 61.9%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 67.1%, transparent 67.1%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 81.2%, transparent 81.2%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }</style><table id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >0</th>        <th class=\"col_heading level0 col1\" >1</th>        <th class=\"col_heading level0 col2\" >2</th>        <th class=\"col_heading level0 col3\" >3</th>        <th class=\"col_heading level0 col4\" >4</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0level0_row0\" class=\"row_heading level0 row0\" >1/2</th>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col0\" class=\"data row0 col0\" >0.180962</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col1\" class=\"data row0 col1\" >0.318738</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col2\" class=\"data row0 col2\" >0.216757</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col3\" class=\"data row0 col3\" >1.42131</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row0_col4\" class=\"data row0 col4\" >1.6473</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0level0_row1\" class=\"row_heading level0 row1\" >1/4</th>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col0\" class=\"data row1 col0\" >0.427229</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col1\" class=\"data row1 col1\" >0.287581</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col2\" class=\"data row1 col2\" >0.260362</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col3\" class=\"data row1 col3\" >2.06556</td>\n",
       "                        <td id=\"T_c28e23e3_53eb_11ea_bcec_d46d6d270ab0row1_col4\" class=\"data row1 col4\" >2.21081</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fb99e4ac5c0>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diff_second_cluster = pd.concat([centers_all.iloc[1,:] - centers_all.iloc[4,:], centers_all.iloc[1,:] - centers_all.iloc[7,:]], axis=1, ignore_index=True).transpose()\n",
    "diff_second_cluster.index = [\"1/2\", \"1/4\"]\n",
    "diff_second_cluster.style.bar(subset=[0,1,2,3,4], align='mid', color=['#d65f5f', '#5fba7d'],  width=90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style  type=\"text/css\" >\n",
       "    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#d65f5f 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 79.1%, transparent 79.1%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 12.5%, transparent 12.5%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 21.2%, transparent 21.2%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 33.7%, transparent 33.7%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col0 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg, transparent 20.5%, #d65f5f 20.5%, #d65f5f 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col1 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col2 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col3 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }    #T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col4 {\n",
       "            width:  10em;\n",
       "             height:  80%;\n",
       "            background:  linear-gradient(90deg,#5fba7d 90.0%, transparent 90.0%);\n",
       "        }</style><table id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0\" ><thead>    <tr>        <th class=\"blank level0\" ></th>        <th class=\"col_heading level0 col0\" >0</th>        <th class=\"col_heading level0 col1\" >1</th>        <th class=\"col_heading level0 col2\" >2</th>        <th class=\"col_heading level0 col3\" >3</th>        <th class=\"col_heading level0 col4\" >4</th>    </tr></thead><tbody>\n",
       "                <tr>\n",
       "                        <th id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0level0_row0\" class=\"row_heading level0 row0\" >1/2</th>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col0\" class=\"data row0 col0\" >-0.0389132</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col1\" class=\"data row0 col1\" >0.418558</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col2\" class=\"data row0 col2\" >0.0399649</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col3\" class=\"data row0 col3\" >0.201598</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row0_col4\" class=\"data row0 col4\" >0.31681</td>\n",
       "            </tr>\n",
       "            <tr>\n",
       "                        <th id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0level0_row1\" class=\"row_heading level0 row1\" >1/4</th>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col0\" class=\"data row1 col0\" >-0.0300697</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col1\" class=\"data row1 col1\" >0.476211</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col2\" class=\"data row1 col2\" >0.286904</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col3\" class=\"data row1 col3\" >0.855841</td>\n",
       "                        <td id=\"T_c28e23e4_53eb_11ea_bcec_d46d6d270ab0row1_col4\" class=\"data row1 col4\" >0.845892</td>\n",
       "            </tr>\n",
       "    </tbody></table>"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x7fb99e4179b0>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diff_third_cluster = pd.concat([centers_all.iloc[2,:] - centers_all.iloc[5,:], centers_all.iloc[2,:] - centers_all.iloc[8,:]], axis=1, ignore_index=True).transpose()\n",
    "diff_third_cluster.index = [\"1/2\", \"1/4\"]\n",
    "diff_third_cluster.style.bar(subset=[0,1,2,3,4], color=['#d65f5f', '#5fba7d'], align=\"mid\", width=90)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3rc1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
